﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace eslib.nnp5
{
    public abstract class PkgHandlerApp : MicroFFAppBase
    {

        PkgHandlerAgentPkg.SerializableType serializeType { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="connector"></param>
        /// <param name="handlerProvider"></param>
        /// <param name="serializeType">序列化类型,默认是bson（数据包体积小）</param>
        public PkgHandlerApp(Connector connector,
                             PkgHandlerAgentPkg.SerializableType serializeType = PkgHandlerAgentPkg.SerializableType.bson
            ) : base(connector)
        {
            //数据包处理器初始化
            PkgHandlerInit();

            this.serializeType = serializeType;
        }


        public override void NewPKGEvent(byte[] buffer)
        {
            try
            {
                //以PkgHandlerAgentPkg作中介
                PkgHandlerAgentPkg jpkg = PkgHandlerAgentPkg.Transfer(buffer, serializeType);

                object pkg = jpkg.GetObject();
                Type t = jpkg.GetPkgType();
                CallPkgHandler(pkg, t);
            }
            catch (Exception err)
            {
                PkgReciveError(err);
            }
        }

        /// <summary>
        /// 发送对象化数据包
        /// </summary>
        /// <param name="pkg"></param>
        public void SendObjectPkg<T>(T pkg)
        {
            //以PkgHandlerAgentPkg作中介
            PkgHandlerAgentPkg jpkg = PkgHandlerAgentPkg.CreateNew(pkg, serializeType);
            SendPkg(jpkg);
        }



        #region 数据包处理

        Hashtable methodTable = new Hashtable();



        void addHandlerMethod(MethodInfo mi, Type t)
        {
            methodTable[t] = mi;
        }

        MethodInfo? getHandlerBind(Type t)
        {
            return (MethodInfo?)methodTable[t];
        }


        /// <summary>
        /// 调用数据包处理器
        /// </summary>
        /// <param name="p"></param>
        void CallPkgHandler(object p, Type t)
        {
            MethodInfo? mi = getHandlerBind(t);

            //没有同类型的handler，调用默认处理器
            if (mi == null)
            {
                DefaultHandle(p);
            }
            else
            {
                mi.Invoke(this, [p]);
            }
        }


        void PkgHandlerInit()
        {
            Type t = this.GetType();

            List<MethodInfo> handlers = t.GetMethods().Where(mi => mi.GetCustomAttribute<PkgHandleAttribute>() != null).ToList();

            foreach (MethodInfo mi in handlers)
            {
                ParameterInfo[] prms = mi.GetParameters();
                if (prms.Length != 1) throw new Exception("Handler参数异常");

                Type pt = prms[0].ParameterType;

                addHandlerMethod(mi, pt);
            }
        }


        /// <summary>
        /// 默认数据包处理
        /// 自定义的数据包处理器带[PkgHandle]特性定义即可
        /// </summary>
        /// <param name="p"></param>
        public abstract void DefaultHandle(object p);

        /// <summary>
        /// 数据包接收异常
        /// </summary>
        /// <param name="err"></param>
        public virtual void PkgReciveError(Exception err) { }

        #endregion

    }
}
